27. Tworzenie obiekt≤w


    JavaScript jest jΩzykiem skryptowym obiektowo utwierdzonym. Obiekt jest to taka struktura, kt≤ra mo┐e posiadaµ swoje w│a╢ciwo╢ci, kt≤rymi s▒ nale┐▒ce do tego obiektu zmienne. Obiekt mo┐e r≤wnie┐ posiadaµ powi▒zane ze sob▒ funkcje, kt≤re nazywa siΩ metodami. Opr≤cz obiekt≤w predefiniowanych, JavaScript umo┐liwia nam tworzenie w│asnych obiekt≤w, co zwiΩksza komfort pracy, poniewa┐ kod skryptu staje siΩ wtedy du┐o czytelniejszy i │atwiej siΩ nam jest w nim poruszaµ.

Obiekt w JavaScript mo┐e posiadaµ powi▒zane z nim w│a╢ciwo╢ci. DostΩp do nich odbywa siΩ w nastepuj▒cy spos≤b:

obiekt.w│asno╢µ

Podczas odnoszenia siΩ do obiekt≤w i ich w│a╢ciwo╢ci trzeba zwracaµ uwagΩ na wielko╢µ liter, poniewa┐ dla interpretatora jΩzyka obiekt i Obiekt to nie to samo.

Jest jeszcze druga metoda odnoszenia siΩ do w│asno╢ci obiektu, wynikaj▒ca z tego, ┐e te s▒ ╢ci╢le powi▒zane z tablicami, a mianowicie:

obiekt["w│asno╢µ"]

Przypu╢µmy, ┐e mamy stworzony obiekt "Ja" (jak deklarowaµ same obiekty powiem ju┐ za chwilΩ). Stworzenie nowych w│a╢ciwo╢ci odbywa siΩ poprzez zainincjowanie dla nich warto╢ci, np.:

Ja.imiΩ = "Rafa│";
Ja.wiek = 19;
Ja.wzrost = 1.92;

U┐ywaj▒c sposobu z tablicami, zwanymi asocjacyjnymi, dziΩki interacji for..in, mo┐emy szybko pobraµ i wypisaµ wszystkie w│a╢ciwo╢ci obiektu:

function wypisz(obiekt)
 {
  var wynik = "";
  for (var i in obiekt)
   wynik += "." + i " = " + obiekt[i] + "\n";
  return wynik;
 }

Efektem bΩdzie:

.imiΩ = Rafa│
.wiek = 19
.wzrost = 1.92

Je╢li nie wierzysz, zobacz sam:

Istniej▒ dwie metody stworzenia obiektu. Je╢li chesz u┐ywaµ tylko jednej instancji obiektu, mo┐esz u┐yµ inicjatora obiektu. Natomiast je┐eli bΩd▒ tworzone wielokrotne instancje tego obiektu, powiniene╢ zadeklarowaµ funkcjΩ konstruktor, kt≤r▒ bΩdziesz u┐ywa│ do stworzenia obiektu poprzez operator new.

Inicjator obiektu jest w miarΩ prosty w swej konstrukcji:

nazwa_obiektu = {w│asno╢µ1:warto╢µ1,w│asno╢µ2:warto╢µ2 ...};

Czyli dla naszego obiektu Ja taka deklaracja wygl▒da tak:

var Ja = {imiΩ:"Rafa│",wiek:19,wzrost:1.92};

Obiekt mo┐e mieµ r≤wnie┐ obiekty podrzΩdne. Aby zadeklarowaµ taki piszemy:

var Ja = {imiΩ:"Rafa│",zainteresowania:{sport:"koszyk≤wka",
komputery:"programowanie"}};

W tym przypadku obiekt Ja posiada jedn▒ w│a╢ciowo╢µ: imiΩ oraz obiekt podrzΩdny zainteresowania z dwiema w│a╢ciwo╢ciami.

Aby uzyskaµ dostΩp do w│a╢ciwo╢ci sport piszemy analogicznie zwracaj▒c uwagΩ na hierarchiΩ obiekt≤w:

Ja.zainteresowania.sport

Alternatywnym rozwi▒zaniem dla tego typu deklaracji jest napisanie konstruktora, czyli funkcji inicjuj▒cej tworzony obiekt. Funkcja taka zazwyczaj pobiera parametry, kt≤re ustawia jako nowe w│a╢ciwo╢ci obiektu oraz inicjuje ich warto╢ci. Konstruktor okre╢la typ obiektu, czyli oznacza to, ┐e bΩdziemy deklarowaµ nasz obiekt z u┐yciem operatora new. Aby stworzyµ obiekt Ja musimy napisaµ konstruktor dla typu o nazwie powiedzmy "osoba":

function osoba(imiΩ,wiek)
 {
  this.imiΩ = imiΩ;
  this.wiek = wiek;
 }

var Ja = new osoba("Rafa│",19);
Ja.wzrost = 1.92;

Przypisanie nastΩpuje poprzez instrukcjΩ this, dlatego, aby te dane nie by│y warto╢ciami lokalnymi a powi▒zanymi z obiektem w│a╢ciwo╢ciami. Zauwa┐my, ┐e konstruktor nie deklaruje w│a╢ciwo╢ci wzrost, kt≤ra deklarowana jest dopiero p≤╝niej poprzez nadanie jej warto╢ci. Taki rodzaj deklaracji (u┐ywaj▒c new) pozna│e╢ ju┐ deklaruj▒c obiekty typu String, czy Date.

Korzystaj▒c z naszej funkcji wypisuj▒cej w│a╢ciwo╢ci obiekt≤w, zobaczmy, czy to dzia│a:

Aby stworzyµ obiekt podrzΩdny, trzeba napisaµ, np.:

function hobby()
 {
  this.sport = "koszyk≤wka";
  this.komputery = "programowanie"
 }

function osoba(imiΩ,wiek)
 {
  this.imiΩ = imiΩ;
  this.wiek = wiek;
  this.zainteresowania = new hobby;
 }

Tym sposobem mamy w Ja podobiekt zainteresowania typu hobby z dwoma w│a╢ciwo╢ciami.

Jak ju┐ wspomnia│em obiekt mo┐e posiadaµ metody, czyli powi▒zane ze sob▒ funkcje. MetodΩ deklarujemy tak, jak standardow▒ funkcjΩ (co dok│adniej opisane jest w lekcji 7) a podpina siΩ j▒ w identyczny spos≤b jak w│a╢ciowo╢µ:

function sprawdz_imiΩ()
 {
  if (this.imiΩ == "Rafa│")
   return "Ja te┐ mam tak na imiΩ!!!"
  else
   return "úadne imiΩ " + this.imiΩ;
 }

function osoba2(imiΩ,wiek)
 {
  this.imiΩ = imiΩ;
  this.wiek = wiek;
  this.sprawdz_imiΩ = sprawdz_imiΩ;
 }

var Ja = new osoba2("Rafa│",19);

..i wywo│anie metody w przycisku:

onClick="alert(Ja.sprawdz_imiΩ())"

co w praktyce wygl▒da nastΩpuj▒co:

Jak widzimy w funkcji, kt≤ra jest deklaracj▒ metody, do obiektu ojczystego odnosimy siΩ r≤wnie┐ poprzez this.

W JavaScript mo┐liwa jest modyfikacja wszystkich instancji danego typu obiektu. Mo┐liwe jest to dziΩki odniesieniu siΩ do prototypu obiektu:

Ja.prototype.gatunek = "cz│owiek";

Od tej pory wszystkie obiekty utworzone za pomoc▒ tego samego konstruktora, co obiekt Ja posiada now▒ w│a╢ciwo╢µ gatunek o warto╢ci "cz│owiek".

Pocz▒wszy od trzeciej ods│ony sk│adni JavaScript mo┐emy u┐ywaµ takiego operatora jak delete, kt≤ry umo┐liwia nam kasowanie w│a╢ciwo╢ci obiektu. Jeszcze w JavaScript dla Netscape Navigator 2.0 nie mo┐na by│o usuwaµ obiekt≤w, jednak┐e ju┐ od nowszej wersji dla Netscape Navigator 3.0, wykonuje siΩ to poprzez ustawienie ostatniej referencji do obiektu na null.